﻿using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Windows.Devices.Enumeration;
using Windows.Media.Capture;
using Windows.Media.Devices;
using Windows.Media.MediaProperties;
using Windows.Storage.Streams;
using Windows.Storage;
using Windows.UI.Xaml.Controls;
using System.Text.RegularExpressions;

namespace SampleMediaCaptureNet
{
    /// <summary>
    /// 摄像头显示Demo，通过UWP-WindowsXamlHost承载画面（置顶），直接用CaptureElement渲染速度很快。实现逻辑同windows系统相机
    /// </summary>
    public partial class MainWindow : Window
    {
        private CaptureElement _captureElement;
        public MediaCapture _mediaCapture;
        VideoDeviceController videoController;

        public MainWindow()
        {
            InitializeComponent();
            AddUwpElement();
        }

        /// <summary>
        /// 添加UWP控件
        /// </summary>
        private void AddUwpElement()
        {
            Windows.UI.Xaml.Controls.Grid mainGrid = new Windows.UI.Xaml.Controls.Grid();
            var captureElement = _captureElement = new CaptureElement()
            {
                Stretch = Windows.UI.Xaml.Media.Stretch.UniformToFill
            };
            mainGrid.Children.Add(captureElement);
            VideoViewHost.Child = mainGrid;
        }

        /// <summary>
        /// 打开摄像头
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void bOpen_OnClick(object sender, RoutedEventArgs e)
        {
            _mediaCapture = new MediaCapture();
            var videos = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
            var settings = new MediaCaptureInitializationSettings()
            {
                VideoDeviceId = videos[0].Id,

                StreamingCaptureMode = StreamingCaptureMode.Video,
            };

            await _mediaCapture.InitializeAsync(settings);




            // 获取视频设备控制器 
            videoController = _mediaCapture.VideoDeviceController;

            if (videoController.Brightness.Capabilities.Supported)
            {
                // 亮度可调 
                System.Diagnostics.Debug.WriteLine("亮度可调");
            }
            else
            {
                // 亮度不可调   
                System.Diagnostics.Debug.WriteLine("亮度不可调");
            }
            if (videoController.Contrast.Capabilities.Supported)
            {
                // 对比度可调
                System.Diagnostics.Debug.WriteLine("对比度可调");
            }
            else
            {
                // 对比度不可调
                System.Diagnostics.Debug.WriteLine("对比度不可调");
            }


            if (videoController.WhiteBalance.Capabilities.Supported)
            {
                //白平衡可调
                System.Diagnostics.Debug.WriteLine("白平衡可调");
            }
            else
            {
                //白平衡不可调
                System.Diagnostics.Debug.WriteLine("白平衡不可调");
            }

            if (videoController.Hue.Capabilities.Supported)
            {
                //色调可调
                System.Diagnostics.Debug.WriteLine("色调可调");
            }
            else
            {
                //色调不可调
                System.Diagnostics.Debug.WriteLine("色调不可调");
            }



            ////显示WindowsXamlHost
            //VideoViewHost.Visibility = Visibility.Visible;
            //绑定画面源
            _captureElement.Source = _mediaCapture;
            await _mediaCapture.StartPreviewAsync();



            //搜索设备所有分辨率
            IEnumerable<StreamResolution> allVideoProperties = _mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.VideoRecord).Select(x => new StreamResolution(x));

            //查询当前分辨率
            StreamResolution previewProperties = new StreamResolution(_mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview));

            // Get all formats that have the same-ish aspect ratio as the preview
            // Allow for some tolerance in the aspect ratio comparison
            const double ASPECT_RATIO_TOLERANCE = 0.015;
            var matchingFormats = allVideoProperties;//.Where(x => Math.Abs(x.AspectRatio - previewProperties.AspectRatio) < ASPECT_RATIO_TOLERANCE);

            // Order them by resolution then frame rate
            allVideoProperties = matchingFormats.OrderByDescending(x => x.Height * x.Width).ThenByDescending(x => x.FrameRate);


            cbVideo.Items.Clear();
            int _index = 0;
            foreach (var property in allVideoProperties)
            {
                System.Windows.Controls.ComboBoxItem comboBoxItem = new System.Windows.Controls.ComboBoxItem();
                comboBoxItem.Content = property.GetFriendlyName();
                comboBoxItem.Tag = property;
                cbVideo.Items.Add(comboBoxItem);

                if (previewProperties.GetFriendlyName() == property.GetFriendlyName())
                {
                    cbVideo.SelectedIndex = _index;
                }
                _index++;
            }

            double now = 0;
            videoController.Brightness.TryGetValue(out now);
            //System.Diagnostics.Debug.WriteLine("当前值为" + now);
            sliderBrightness.Value = now;
            tbBrightness.Text = "亮度" + now;


            videoController.Contrast.TryGetValue(out now);
            //System.Diagnostics.Debug.WriteLine("当前值为" + now);
            sliderContrast.Value = now;
            tbContrast.Text = "对比度" + now;



            videoController.Hue.TryGetValue(out now);
            //System.Diagnostics.Debug.WriteLine("当前值为" + now);
            sliderHue.Value = now;
            tbHue.Text = "色调" + now;
        }

        /// <summary>
        /// 选择分辨率
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void cbVideo_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            if (cbVideo.SelectedIndex > -1)
            {
                var selectedItem = (sender as System.Windows.Controls.ComboBox).SelectedItem as System.Windows.Controls.ComboBoxItem;
                var encodingProperties = (selectedItem.Tag as StreamResolution).EncodingProperties;

                await _mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoRecord, encodingProperties);

                //获取当前分辨率
                var props = (VideoEncodingProperties)_mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview);
                string tmpResolution = props.Width.ToString() + "x" + props.Height.ToString();

                tbRecord.Text = tmpResolution;
            }
        }


        private bool isRecording = false;
        private string recordState = "";

        private InMemoryRandomAccessStream _randomAccessStream;


        /// <summary>
        /// 开始和停止录制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnRecord_Click(object sender, RoutedEventArgs e)
        {
            if (!isRecording)
            {
                try
                {

                    //获取当前分辨率
                    var props = (VideoEncodingProperties)_mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview);
                    string tmpResolution = props.Width.ToString() + "x" + props.Height.ToString();

                    string FileName = DateTime.Now.ToString("yyMMdd_HH_mm_ss_") + tmpResolution + ".mp4";

                    var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);

                    // Fall back to the local app storage if the Pictures Library is not available
                    cFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;

                    // Create storage file in Video Library
                    var videoFile = await cFolder.CreateFileAsync("_SampleMeidaCaptureNet\\" + FileName, CreationCollisionOption.GenerateUniqueName);

                    // 根据需要选择不同视频输出格式，别忘记改上面的扩展名
                    //var encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto); //h.264
                    //var encodingProfile = MediaEncodingProfile.CreateAvi(VideoEncodingQuality.Auto);
                    //var encodingProfile = MediaEncodingProfile.CreateWmv(VideoEncodingQuality.Auto);
                    var encodingProfile = MediaEncodingProfile.CreateHevc(VideoEncodingQuality.Auto); //h.265

                    // 开始录制
                    await _mediaCapture.StartRecordToStorageFileAsync(encodingProfile, videoFile);



                    //更改UI内容
                    btnRecord.Content = "停止录像";
                    isRecording = true;

                    cbVideo.IsEnabled = false;
                    btnPhoto.IsEnabled = false;


                    recordState = "正在录像 ";
                }
                catch (Exception ex)
                {
                    // File I/O errors are reported as exceptions.
                }
            }
            else
            {
                // Reflect the changes in UI and stop recording
                recordState = "录像停止 ";
                btnRecord.Content = "开始录像";
                isRecording = false;


                await _mediaCapture.StopRecordAsync();
                cbVideo.IsEnabled = true;
                btnPhoto.IsEnabled = true;


                //MessageBox.Show("视频已保存在'我的图片\_SampleMediaCaptureNet'之中");
            }
        }

        private StorageFolder cFolder = null;
        /// <summary>
        /// 拍照
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnPhoto_Click(object sender, RoutedEventArgs e)
        {
            var stream = new InMemoryRandomAccessStream();

            try
            {
                //获取当前分辨率
                var props = (VideoEncodingProperties)_mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview);
                string tmpResolution = props.Width.ToString() + "x" + props.Height.ToString();

                string FileName = DateTime.Now.ToString("yyMMdd_HH_mm_ss_") + tmpResolution + ".jpg";
                var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
                // Fall back to the local app storage if the Pictures Library is not available
                cFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
                // Take and save the photo
                var file = await cFolder.CreateFileAsync("_SampleMeidaCaptureNet\\" + FileName, CreationCollisionOption.GenerateUniqueName);
                await _mediaCapture.CapturePhotoToStorageFileAsync(ImageEncodingProperties.CreateJpeg(), file);

                //MessageBox.Show("照片已保存在'我的图片\_SampleMediaCaptureNet'之中");
            }
            catch (Exception ex)
            {
                //出错处理
            }
        }


        /// <summary>
        /// 改变亮度
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sliderBrightness_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (videoController == null)
            {
                return;
            }

            if (videoController.Brightness.TrySetValue(sliderBrightness.Value)) // 范围通常为 0.0~1.0
            {
                // 设置成功 
                System.Diagnostics.Debug.WriteLine("设置成功");
                //tbTip.Text = "设置成功";
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("设置失败");
                //tbTip.Text = "设置失败";
            }
            double now = 0;
            videoController.Brightness.TryGetValue(out now);
            System.Diagnostics.Debug.WriteLine("当前值为" + now);
            tbBrightness.Text = "亮度" + now;
        }

        /// <summary>
        /// 更改对比度
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sliderContrast_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (videoController == null)
            {
                return;
            }

            if (videoController.Contrast.TrySetValue(sliderContrast.Value)) // 范围通常为 0.0~1.0
            {
                // 设置成功 
                System.Diagnostics.Debug.WriteLine("设置成功");
                //tbTip.Text = "设置成功";
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("设置失败");
                //tbTip.Text = "设置失败";
            }
            double now = 0;
            videoController.Contrast.TryGetValue(out now);
            System.Diagnostics.Debug.WriteLine("当前值为" + now);
            tbContrast.Text = "对比度" + now;
        }


        /// <summary>
        /// 更改色调
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sliderHue_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (videoController == null)
            {
                return;
            }

            if (videoController.Hue.TrySetValue(sliderHue.Value)) // 范围通常为 0.0~1.0
            {
                // 设置成功 
                System.Diagnostics.Debug.WriteLine("设置成功");
                //tbTip.Text = "设置成功";
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("设置失败");
                //tbTip.Text = "设置失败";
            }
            double now = 0;
            videoController.Hue.TryGetValue(out now);
            System.Diagnostics.Debug.WriteLine("当前值为" + now);
            tbHue.Text = "色调" + now;
        }
    }
}

